package com.m3958.firstgwt.server.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import nl.captcha.Captcha;


import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.m3958.firstgwt.server.dao.UserDao;
import com.m3958.firstgwt.server.model.User;
import com.m3958.firstgwt.server.model.WebSite;
import com.m3958.firstgwt.server.service.AppUtilService;
import com.m3958.firstgwt.server.service.MySHAService;
import com.m3958.firstgwt.server.service.RequestScopeObjectService;
import com.m3958.firstgwt.server.session.SessionUser;

@Singleton
public class LoginServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	

	@Inject
	private AppUtilService apputils;
	
	@Inject
	private Injector injector;
	
	@Inject
	private com.google.inject.Provider<EntityManager> emp;
	
	
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res) 
	                               throws ServletException, IOException {
		Map<String,Object> rootDataModel = new HashMap<String, Object>();
		String next = req.getParameter("next");
		if(next == null || next.isEmpty())next="sitebuilder";
		rootDataModel.put("next", next);
		rootDataModel.put("showCaptcha", false);
		SessionUser su = injector.getInstance(SessionUser.class);
		
		if(su.isLogined()){
			RequestScopeObjectService rso = injector.getInstance(RequestScopeObjectService.class);
			String redirectUrl = getRedirectUrl(req, rso, next);
			if(sendQianfeiPage(req, res, su.getUserId(), redirectUrl))return;
			res.sendRedirect(redirectUrl);
			return;
		}
		Integer loginFailureTimes = (Integer) req.getSession().getAttribute("LOGIN_FAILURE_TIMES");
		
		if(loginFailureTimes != null && loginFailureTimes > 6){
			rootDataModel.put("showCaptcha", true);
		}
		
		res.setContentType("text/html;charset=UTF-8");   
		res.setCharacterEncoding("UTF-8");
		apputils.sendWebContextTpl(req, res, "logintpls/login.ftl",rootDataModel);
	}
	
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res) 
	                               throws ServletException, IOException {
		
		String userName = req.getParameter("username");
		String password = req.getParameter("password");
		String answer = req.getParameter("answer");
		String next = req.getParameter("next");
		
		if(next == null || next.isEmpty())next="sitebuilder";
		
		UserDao udao = injector.getInstance(UserDao.class);
		User user = udao.findByLoginNameOrEmailOrMobile(userName);
		
		Integer loginFailureTimes = (Integer) req.getSession().getAttribute("LOGIN_FAILURE_TIMES");
		if(loginFailureTimes == null)loginFailureTimes = 0;
		
		req.getSession().setAttribute("LOGIN_FAILURE_TIMES",++loginFailureTimes);
		
		List<String> errorScripts = new ArrayList<String>();
		
		if(loginFailureTimes > 7){
			Captcha captcha = (Captcha) req.getSession().getAttribute(Captcha.NAME);
			if(captcha == null || !captcha.isCorrect(answer)){
				errorScripts.add("showhideerror('answer',true);");
			}
		}
		
		if(errorScripts.isEmpty()){
			if(user != null){
				MySHAService shas = injector.getInstance(MySHAService.class);
				if(shas.isEqual(user.getPassword(), password)){
					RequestScopeObjectService rso = injector.getInstance(RequestScopeObjectService.class);
					SessionUser su = injector.getInstance(SessionUser.class);
					su.setContent(user);
					req.getSession().removeAttribute("LOGIN_FAILURE_TIMES");
					req.getSession().removeAttribute(Captcha.NAME);

					String redirectUrl = getRedirectUrl(req, rso, next);
					
					if(sendQianfeiPage(req, res, user.getId(), redirectUrl))return;

					res.sendRedirect(redirectUrl);
					return;
				}else{
					errorScripts.add("showhideerror('password',true);");
				}
			}else{
				errorScripts.add("showhideerror('password',true);");
			}
		}
		
		Map<String,Object> rootDataModel = new HashMap<String, Object>();
		rootDataModel.put("next", next);
		rootDataModel.put("username", userName);
		if(loginFailureTimes > 6){
			rootDataModel.put("showCaptcha", true);
		}else{
			rootDataModel.put("showCaptcha", false);
		}
		rootDataModel.put("errorScripts", errorScripts);
		res.setContentType("text/html;charset=UTF-8");   
		res.setCharacterEncoding("UTF-8");
		apputils.sendWebContextTpl(req, res, "logintpls/login.ftl",rootDataModel);
	}
	
	
	private String getRedirectUrl(HttpServletRequest req,RequestScopeObjectService rso,String next){
		boolean inDebug = req.getRequestURL().toString().contains(":8888");
		String redirectUrl = "";
		
		if("sitebuilder".equals(next)){
			redirectUrl = "/FirstGwt.html";
		}
		if(inDebug){
			redirectUrl = redirectUrl + "?gwt.codesvr=127.0.0.1:9997";
		}else{
			redirectUrl = "http://" + rso.getRequestHostName() + redirectUrl;
		}
		return redirectUrl;
	}
	
	private boolean sendQianfeiPage(HttpServletRequest req, HttpServletResponse res,int userId,String redirectUrl){
		String qs = "SELECT DISTINCT(s) FROM WebSite AS s,IN(s.objectPermissions) AS p WHERE p.id IN (SELECT q.id FROM User AS u,IN(u.roles) AS r,IN(r.permissions) AS q WHERE  u.id = :uid) AND s.serviceEndDate < :endDate";
		Query q = emp.get().createQuery(qs);
		q.setParameter("uid", userId);
		q.setParameter("endDate", new Date());
		SessionUser su = injector.getInstance(SessionUser.class);
		List<WebSite> ws = q.getResultList();
		
		if(ws.size() > 0){
			res.setContentType("text/html;charset=UTF-8");   
			res.setCharacterEncoding("UTF-8");
			Map<String,Object> rootDataModel = new HashMap<String, Object>();
			rootDataModel.put("websitelist", ws);
			rootDataModel.put("nexturl",redirectUrl);
			apputils.sendWebContextTpl(req, res, "logintpls/qianfeitip.ftl",rootDataModel);
			//人工指定不准登录
			if(!su.isSuperman()){
				for(WebSite w : ws){
					if(w.isOutOfService()){
						su.clearContent();
						break;
					}
				}
			}
			return true;
		}
		return false;
	}
}
